#define ZCORE_SOURCE
#include "Thread.hpp"

#ifdef ZZZ_LIB_PTHREAD

namespace zzz{
void *__start_thread(void *p)
{
  Thread *pt=(Thread*)p;
  pt->running=true;
  pt->Main();
  pt->running=false;
//  pthread_exit(NULL);
  return NULL;
}

Thread::Thread()
{
  running=false;
}

void Thread::Start()
{
  pthread_attr_t attr; 
  pthread_attr_init(&attr); 
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  int rc = pthread_create(&thread, &attr, __start_thread, (void *)this); 
  pthread_attr_destroy(&attr);
}

void Thread::Wait()
{
  void *status;
  int rc = pthread_join(thread, &status);
}

bool Thread::IsRunning()
{
  return running;
}

Mutex::Mutex()
{
  pthread_mutex_init(&mutex, NULL);
}

Mutex::~Mutex()
{
  pthread_mutex_destroy(&mutex);
}

void Mutex::Lock()
{
  pthread_mutex_lock(&mutex); 
}

void Mutex::Unlock()
{
  pthread_mutex_unlock(&mutex); 
}

bool Mutex::TryLock()
{
  if (pthread_mutex_trylock(&mutex)==0) return true;
  else return false;
}

Condition::Condition()
{
  pthread_mutex_init(&mutex,NULL);
  pthread_cond_init(&cond,NULL);
}

Condition::~Condition()
{
  pthread_mutex_destroy(&mutex);
  pthread_cond_destroy(&cond);
}

void Condition::Check()
{
  pthread_mutex_lock(&mutex);
  if (IsSatisfied()) pthread_cond_signal(&cond);
  pthread_mutex_unlock(&mutex);
}

void Condition::Wait()
{
  pthread_mutex_lock(&mutex);
  pthread_cond_wait(&cond, &mutex);
  pthread_mutex_unlock(&mutex);
}
}
#endif // ZZZ_LIB_PTHREAD
